package com.hzit.aspect;

import com.alibaba.fastjson.JSON;
import com.hzit.annotation.RequiresPermissions;
import com.hzit.constants.TokenConstants;
import com.hzit.entity.LoginUser;
import com.hzit.exception.NotPermissionException;
import com.hzit.util.JwtUtil;
import io.jsonwebtoken.Claims;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;


@Component
@Aspect
public class PreAuthorizeAspect {
	@Autowired
	private StringRedisTemplate redisTemplate;


	@Around("@annotation(rp)")
	public Object innerAround(ProceedingJoinPoint point, RequiresPermissions rp) throws Throwable{
		String[] value = rp.value();
		LoginUser loginUser = getLoginUser();
		List<String> permissions = loginUser.getPermissions();
		boolean b = matchPermission(value,permissions);
		if(!b){
			String replace = Arrays.toString(value).replace("[", "").replace("]", "");
			throw  new NotPermissionException("对" + replace + "没有权限访问！");
		}

		return point.proceed();
	}

	private boolean matchPermission(String[] value, List<String> permissions) {
		for (String s : value) {
			 return permissions.contains(s);
		}
		return false;
	}

	private LoginUser getLoginUser() {

		ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		HttpServletRequest request = attributes.getRequest();
		String header = request.getHeader(TokenConstants.AUTHENTICATION);
		String token = getToken(header);

		Claims claims = JwtUtil.parseToken(token);

		String uuidToken  = (String) claims.get(TokenConstants.JWT_TOKEN);

		String redisKey = getRedisKey(uuidToken);

		String loginUserStr = redisTemplate.opsForValue().get(redisKey);

		LoginUser loginUser = JSON.parseObject(loginUserStr, LoginUser.class);
		return loginUser;

	}

	private String getToken(String header) {
		if(header.startsWith("Bearer ")){
			return header.replaceAll(TokenConstants.PREFIX, "");
		}
		return null;
	}

	private String getRedisKey(String uuidToken) {
		return TokenConstants.REDIS_PREFIX + uuidToken;
	}
}
